/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module mdlfuncs.c - Card Type functionality |
   @end

$Log: /SoftPay/SPK2SIM/Source/Tran/mdlfuncs.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#define MDLFUNCS_C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <acldev.h>
#include <aclstr.h>
#include <errno.h>

#include <project.h>
/** /#define DEBUG_MDLFUNCS_C*/
#ifdef DEBUG_MDLFUNCS_C
#define DEBUG_95
#endif

#include <accum.h>
#include <define.h>
#include <spdebug.h>
#include <bdt.h>
#include <cdt.h>
#include <cst.h>
#include <hdt.h>
#include <tct.h>
#include <msg.h>
#include <msgfuncs.h>
#include <card.h>
#include <tran.h>
#include <transact.h>
#include <table.h>
#include <funcids.h>
#include <mdlfuncs.h>
#include <mit.h>
#include <tblutil.h>
#include <codesec.h>
#include <pinpad.h>
#include <pinmsg.h>
#include <pbatch.h>
#include <ui.h>
#include <trt.h>
#include <mbtxmsg.h>
#ifdef MOBITEX_DEFINED
#include <mbtx.h>
#endif
#include <mbtx2.h>
#include <mbtx3.h>
#include <gds.h>

int inCheckBannedCardType(TRANSACTION_OBJECT* pobTran);

/*********************************************************************************************
* @func VS_BOOL | fChkAllHostBatches |
*       Checks to see if the host batches are empty.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Returns VS_TRUE if all host batches are empty, VS_FALSE otherwise.
* @flag int    |  VS_TRUE   |
* @flag int    |  VS_FALSE  |
* @end
**********************************************************************************************/

VS_BOOL fChkAllHostBatches(TRANSACTION_OBJECT* pobTran) {
#ifdef BATCH_DEFINED
    int inCount;
    int inNoMITRecs = inGetMITTotRecs();
    VS_BOOL fIsBatchEmpty;

    /** /pdebug (("--fChkAllHostBatches--"));*/
    /** /pdebug (("inNoMITRecs = %d",inNoMITRecs));*/
    for (inCount = 0; inCount < inNoMITRecs; inCount++) {
        inLoadMITRec(inCount);
        fIsBatchEmpty = fBatchEmpty(pobTran, VS_TRUE);
        if (fIsBatchEmpty != VS_TRUE)
            return(VS_FALSE);  /* Batch Not empty */
    }
    /** /pdebug (("Batch Empty"));*/

#endif // BATCH_DEFINED

    return(VS_TRUE);  /* Batch empty */
}

/*********************************************************************************************
* @func VS_BOOL | fChkAllOpenTabBatches |
*       Checks all Open Tab Batchs to see if any tab batch file
*       has transactions.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
* @flag int    |  VS_TRUE   |   If the batch is EMPTY  or DOES NOT exist.
* @flag int    |  VS_FALSE  |   If batch exists and NOT EMPTY.
* @end
**********************************************************************************************/
VS_BOOL fChkAllOpenTabBatches(TRANSACTION_OBJECT* pobTran) {
#ifdef BATCH_DEFINED
    int inCount;
    int inNoMITRecs = inGetMITTotRecs();
    int inNumberOfRecordsinBatch;

    /** /pdebug (("inNoMITRecs = %d",inNoMITRecs));*/
    for (inCount = 0; inCount < inNoMITRecs; inCount++) {
        inLoadMITRec(inCount);
        inNumberOfRecordsinBatch = inGetOBatchRecCnt(pobTran);
        if (inNumberOfRecordsinBatch > 0)
            return(VS_FALSE); /* Batch Not empty */
    }
    /** /pdebug (("Batch Empty"));*/

#endif // BATCH_DEFINED

    return(VS_TRUE);  /* Batch empty */
}

/*********************************************************************************************
* @func VS_BOOL | fOpenTabEmpty |
*       Finds the Open Tab Batch and checks to see if batch file
*       is empty for the current host number.  The parameter
*       decides whether it is a offline or online batch
*       NB:     Assumption HDT is loaded before this function is called
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
* @flag int    |  VS_TRUE   |   If the batch is EMPTY  or DOES NOT exist.
* @flag int    |  VS_FALSE  |   If batch exists and NOT EMPTY.
* @end
**********************************************************************************************/

VS_BOOL fOpenTabEmpty(TRANSACTION_OBJECT* pobTran) {
    VS_BOOL fRetVal = VS_TRUE;

#ifdef BATCH_DEFINED

    /** /pdebug(("--fOpenTabEmpty--"));*/
    vdBatchOTOpen(pobTran);
    if (pobTran->dbOTBatch.kfile.num_of_recs > 0L)
        fRetVal = VS_FALSE;

    /** /pdebug(("Tab Batch Empty"));*/

#endif // BATCH_DEFINED

    return (fRetVal);
}

/*********************************************************************************************
* @func VS_BOOL | fBatchEmpty |
*       Finds the batch file name and check the batch file is empty for the
*       current host number. The parameter decides whether it is a offline
*       or online batch
*       NB: Assumption HDT is loaded before this function is called
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc Return values.
* @flag int    |  VS_TRUE   |   If the batch is EMPTY  or DOES NOT exist.
* @flag int    |  VS_FALSE  |   If batch exists and NOT EMPTY.
* @end
**********************************************************************************************/

VS_BOOL fBatchEmpty(TRANSACTION_OBJECT* pobTran,VS_BOOL fClose) {
    VS_BOOL fRetVal = VS_TRUE;
#ifdef BATCH_DEFINED
    VS_BOOL fBatchOpened;

    /** /pdebug(("--fBatchEmpty--"));*/
    fBatchOpened = pobTran->fBatchOpen;
    /** /pdebug(("fBatchOpened=%d",fBatchOpened));*/
    vdBatchDCOpen(pobTran);
    if (pobTran->dbBatch.kfile.num_of_recs > 0L) {
        fRetVal = VS_FALSE;
        /**/pdebug(("Batch NOT Empty!"));/**/
    }
    if (!fBatchOpened && fClose)
        vdCloseDCBatch(pobTran);

#endif // BATCH_DEFINED

    return (fRetVal);
}

/*********************************************************************************************
* @func int | inGetOTBatchRecCnt |
*       Gets the count of record in the Open Tab batch file.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc batch count.
* @end
**********************************************************************************************/

int inGetOTBatchRecCnt(TRANSACTION_OBJECT* pobTran) {
    int inRecCnt = 0;
    VS_BOOL fSkipClose = VS_FALSE;

#ifdef BATCH_DEFINED

    /* Check if batch was open when we came in, in which case we
     * don't close it at the end
     */
    if (pobTran->fOTBatchOpen)
        fSkipClose = VS_TRUE;

    /* Open DC Batch */
    if (inOpenTabBatch(pobTran) != VS_SUCCESS)
        return(VS_ERR);

    /* Get rec Count from DB structure */
    inRecCnt = inGetBatchRecCnt(&pobTran->dbBatch);

    /* Close the DC Batch */
    if (!fSkipClose) {
        if (inCloseTabBatch(pobTran) != VS_SUCCESS)
            return(VS_ERR);
    }

#endif

    return (inRecCnt);
}
/*********************************************************************************************
* @func int | inGetBatchRecCnt |
*       Gets the count of record in the Data Capture batch file.
*
* @parm TRANSACTION_OBJECT *    | pobTran |
*
* @rdesc batch count.
* @end
**********************************************************************************************/


int inGetDCBatchRecCnt(TRANSACTION_OBJECT* pobTran) {
    int inRecCnt = 0;
    VS_BOOL fSkipClose = VS_FALSE;

#ifdef BATCH_DEFINED

    /* Check if batch was open when we came in, in which case we
     * don't close it at the end
     */
    if (pobTran->fBatchOpen)
        fSkipClose = VS_TRUE;

    /* Open DC Batch */
    if (inOpenDCBatch(pobTran) != VS_SUCCESS)
        return(VS_ERR);

    /* Get rec Count from DB structure */
    inRecCnt = inGetBatchRecCnt(&pobTran->dbBatch);

    /* Close the DC Batch */
    if (!fSkipClose) {
        if (inCloseDCBatch(pobTran) != VS_SUCCESS)
            return(VS_ERR);
    }

#endif

    return (inRecCnt);
}

int inGetBatchRecCnt(DB_FILE* psrDBF) {
    int inRecCnt = 0;

    /** /pdebug(("--inGetBatchRecCnt--"));*/

#ifdef BATCH_DEFINED

    inRecCnt = (int) psrDBF->kfile.num_of_recs;
    /** /pdebug (("inRecCnt=%d",inRecCnt));*/

#endif // BATCH_DEFINED

    return(inRecCnt);
}

/*********************************************************************************************
* @func int | inResetAccum |
* Deletes a *.BAK accumulator file if exists, renames the
* current accumulator as *.BAK file, also puts the current
* (settlement) date and time, so that these can be used for later
* reprinting of settlement report.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inResetAccum() {
#ifdef ACCUM_DEFINED

    char szFileName[FILENAME_SIZE + 1];
    DB_FILE srDBFPtr;

    /** /pdebug(("--inResetAccum--"));*/

    vdGetAccumFName(szFileName);
    if ((db_open(&srDBFPtr, szFileName, SIZE_ACCUM_KEY, (O_TRUNC | O_CREAT | O_RDWR))) < 0)
        return(VS_ERR);
    inCloseAccum(&srDBFPtr);

    if (inResetASIFile() != VS_SUCCESS) {
        /** /pdebug(("Bad reset ASI"));*/
        return(VS_ERR);
    }

#endif // ACCUM_DEFINED

    return (VS_SUCCESS);
}
/*********************************************************************************************
* @func int | inGetHostTotals |
*
* Get the amount totals from the batch for particular host.
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @parm ACCUM_REC * | psrHostTotals |
*       Pointer to accumulator Record structure.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

int inGetHostTotals(TRANSACTION_OBJECT* pobTran,ACCUM_REC* psrHostTotals) {
    int inRetVal = VS_ERR;

#ifdef ACCUM_DEFINED

    char szFileName[FILENAME_SIZE + 1];
    DB_FILE srDBFPtr;
    ACCUM_REC srAccumRec;
    ACCUM_KEY srAccumKey;
    long lnRecNum = 0L;
    int inTotalSet,
    inTotalType;
    int inTemp;

    /*ACCUM_REC srCurrencyTotals;*/

    /** /pdebug (("--inGetHostTotals--"));*/

    if (inLoadCSTRec(inGetCurrencyIdx()) != VS_SUCCESS) {
        vdSGErrorMessage(CST_ERR_MSG);
        return (VS_ERR);
    }

    memset((char *) psrHostTotals, 0x00, SIZE_ACCUM_REC);
    for (inTotalSet = 0; inTotalSet < MAX_TOTAL_SETS; inTotalSet++) {
        for (inTotalType = 0; inTotalType < MAX_ACCUM_TYPES; inTotalType++) {
            psrHostTotals->srTotals[inTotalSet].lnCount[inTotalType] = 0L;
            psrHostTotals->srTotals[inTotalSet].lnTipCount[inTotalType] = 0L;
            psrHostTotals->srTotals[inTotalSet].dbAmount[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbTip[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbTax[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbCashBack[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbSurCharge[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbCustom1[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbCustom2[inTotalType] = 0.0;
	#ifdef CITI_SING
	     psrHostTotals->srTotals[inTotalSet].dbCustom3[inTotalType] = 0.0;
            psrHostTotals->srTotals[inTotalSet].dbCustom4[inTotalType] = 0.0;
	#endif
        }
    }

    vdGetAccumFName(szFileName);
    if (db_open(&srDBFPtr, szFileName, SIZE_ACCUM_KEY, O_RDWR) < 1) {
        extern int errno;

        if (errno == ENOENT)
            vdSGErrorMessage(BATCH_EMPTY_MSG);
        else
        {

            vdSGErrorMessage(BATCH_ERR_MSG);
		}
        return(VS_ERR);
    }

    lnRecNum = 0L;
    while (VS_TRUE) {
        /** /pdebug (("RecNum=%ld",lnRecNum));*/

        if ((inTemp = db_read(&srDBFPtr, &srAccumKey, (char *) &srAccumRec, SIZE_ACCUM_REC, lnRecNum)) != (int) SIZE_ACCUM_REC)
            break;

        for (inTotalSet = 0; inTotalSet < MAX_TOTAL_SETS; inTotalSet++) {
            for (inTotalType = 0; inTotalType < MAX_ACCUM_TYPES; inTotalType++) {
                psrHostTotals->srTotals[inTotalSet].lnCount[inTotalType] += srAccumRec.srTotals[inTotalSet].lnCount[inTotalType];
                psrHostTotals->srTotals[inTotalSet].lnTipCount[inTotalType] += srAccumRec.srTotals[inTotalSet].lnTipCount[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbAmount[inTotalType] += srAccumRec.srTotals[inTotalSet].dbAmount[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbTip[inTotalType] += srAccumRec.srTotals[inTotalSet].dbTip[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbTax[inTotalType] += srAccumRec.srTotals[inTotalSet].dbTax[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbCashBack[inTotalType] += srAccumRec.srTotals[inTotalSet].dbCashBack[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbSurCharge[inTotalType] += srAccumRec.srTotals[inTotalSet].dbSurCharge[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbCustom1[inTotalType] += srAccumRec.srTotals[inTotalSet].dbCustom1[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbCustom2[inTotalType] += srAccumRec.srTotals[inTotalSet].dbCustom2[inTotalType];
		#ifdef CITI_SING
		  psrHostTotals->srTotals[inTotalSet].dbCustom3[inTotalType] += srAccumRec.srTotals[inTotalSet].dbCustom3[inTotalType];
                psrHostTotals->srTotals[inTotalSet].dbCustom4[inTotalType] += srAccumRec.srTotals[inTotalSet].dbCustom4[inTotalType];
		#endif
            }
        }
        lnRecNum++;
    }
    inCloseAccum(&srDBFPtr);
    inRetVal = VS_SUCCESS;

#endif // ACCUM_DEFINED

    return (inRetVal);
}

/*********************************************************************************************
* @func void | vdFlushCardBuffer |
*
*       Read data from card reader buffer to clean it. CARD_SIZE is
*       the size of data read from card device.
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdFlushCardBuffer(void) {
    char stDummyBuf[CARD_SIZE + 1];

    while (read(hCardReader, stDummyBuf, CARD_SIZE) > 0) ;
}

/*********************************************************************************************
* @func int | inCheckTrackOneData |
*
* @parm struct TRACK *  | psrCardData   |
* @parm int     | inResult  |
*
* @rdesc Return values.
* @flag int    |  VS_SUCCESS    |
* @flag int    |  VS_ERR        |
* @end
**********************************************************************************************/

int inCheckTrackOneData(struct TRACK* psrCardData,int inResult) {
    int inStatus = VS_SUCCESS;
    long lnErr;

    lnErr = 0L;

    if (inResult != TK_1) {
        lnErr = (long) inResult;
        inStatus = VS_ERR;
    } else if (strlen(psrCardData->name) > MAX_TRACK1_NAME_SIZE) {
        lnErr = TRACK_NAME_TOO_LONG_ERR_MSG21;
        inStatus = VS_ERR;
    }

    if (inStatus == VS_ERR)
        vdGetCardParseError(lnErr);

    return(inStatus);
}

/*********************************************************************************************
* @func int | inCheckTrackTwoData |
*
* @parm struct TRACK *  | psrCardData   |
* @parm int     | inResult  |
*
* @rdesc Return values.
* @flag int    |  VS_SUCCESS    |
* @flag int    |  VS_ERR        |
* @end
**********************************************************************************************/

int inCheckTrackTwoData(struct TRACK* psrCardData,int inResult) {
    int inStatus;
    long lnErr;

    inStatus = VS_SUCCESS;
    lnErr = 0L;

    if (inResult != TK_2) {
        lnErr = (long) inResult;
        inStatus = VS_ERR;
    } else if (strlen(psrCardData->acct) > PAN_SIZE) {
        lnErr = TRACK_PANSIZE_LONG_ERR_MSG21;
        inStatus = VS_ERR;
    }

    if (inStatus == VS_ERR)
        vdGetCardParseError(lnErr);

    return(inStatus);
}


/*********************************************************************************************
* @func int | inCheckTrackThreeData |
*
* @parm struct TRACK *  | psrCardData   |
* @parm int     | inResult  |
*
* @rdesc Return values.
* @flag int    |  VS_SUCCESS    |
* @flag int    |  VS_ERR        |
* @end
**********************************************************************************************/

int inCheckTrackThreeData(struct TRACK* psrCardData,int inResult) {
    int inStatus;
    long lnErr;

    inStatus = VS_SUCCESS;
    lnErr = 0L;

    if (inResult != TK_3) {
        lnErr = (long) inResult;
        inStatus = VS_ERR;
    }

    /* Right now I don't think Track 3 is standardized so let's not */
    /* mandate the account # length - mdm - 08/02/00 */
    /*
    else

        if (strlen(psrCardData->acct) > PAN_SIZE)
        {
            lnErr = TRACK_PANSIZE_LONG_ERR_MSG;
            inStatus = VS_ERR;
        }
       */
    if (inStatus == VS_ERR)
        vdGetCardParseError(lnErr);

    return(inStatus);
}

/*********************************************************************************************
* @func void | vdGetCardParseError |
*
*       If the card is a valid one the corresponding CDT will be
*       loaded automatically. No need to explicitly call inLoadCDT().
*       Also the PAN is copied to GDS.  It Card Label is given it searches
*       on label first.
*
* @parm long    | lnErrNum  |
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdGetCardParseError(long lnErrNum) {
    long lnMsg;

    if (lnErrNum == (long) TK_NOT_FOUND)
        lnMsg = NO_TRACK_MSG21;
    else if (lnErrNum == TRACK_PANSIZE_LONG_ERR_MSG21)
        lnMsg = TRACK_PANSIZE_LONG_ERR_MSG21;
    else if (lnErrNum == TRACK_NAME_TOO_LONG_ERR_MSG21)
        lnMsg = TRACK_NAME_TOO_LONG_ERR_MSG21;
    else
        lnMsg = FRAME_ERR_MSG21;

    vdSGErrorMessage(lnMsg);
}
/*********************************************************************************************
* @func VS_BOOL |  fCustomFPSQualifier |
*
*       Runs the custom function which determines if a transaction
*       qualifies for Fast Payment.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
* @flag VS_BOOL    |  VS_TRUE       |
* @flag VS_BOOL    |  VS_FALSE      |
* @end
**********************************************************************************************/

VS_BOOL fCustomFPSQualifier(TRANSACTION_OBJECT* pobTran) {
    VS_BOOL fRetVal = VS_FALSE;
    PFI_TO pinCustomQualifierFunction;

    if ((pinCustomQualifierFunction = inGetFunctionPointer(FPS_QUALIFIER_FUNCTION)) != NULL_PFI)
        fRetVal = pinCustomQualifierFunction(pobTran);

    return (fRetVal);
}

int inDefaultFPSQualifierFunction(TRANSACTION_OBJECT* pobTran) {
    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func VS_BOOL | fFPSQualified |
*
*       Determines if transaction qualifies for Fast Payment.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
* @flag VS_BOOL    |  VS_TRUE       |
* @flag VS_BOOL    |  VS_FALSE      |
* @end
**********************************************************************************************/

VS_BOOL fFPSQualified(TRANSACTION_OBJECT* pobTran) {
    VS_BOOL fRetVal = VS_FALSE;
    long int lnTransAmount;

#ifdef CARD_DEFINED

    lnTransAmount = pobTran->srBKey.lnTotalOfTransactionAmount;

    /* Don't allow FPS or Floor limits for Debit or EBT cards */
    if (inGetType() == DEBIT_CARD || inGetType() == EBT_CARD)
        return(VS_FALSE);

    /*Bug fix from SPBASE2.5J for fast pay. Returns false for Master Card
    transactions over the floor amount limit 09/27/99 gw */

    if (fGetCheckFloorLimit(pobTran)) {
        switch (inGetFPSType()) {
        case  FPS_FLOOR:
            if (lnTransAmount <= lnGetFloorLimitAmount())
                fRetVal = VS_TRUE;
            break;

        case FPS_AX_QRS:
            fRetVal = VS_TRUE;
            break;

        case FPS_VISA_EXP:
            if ((lnTransAmount <= lnGetFloorLimitAmount()) || (lnTransAmount <= lnGetSignLimitAmount()))
                fRetVal = VS_TRUE;
            break;

        case FPS_MC_QUICK:
            if (lnTransAmount <= lnGetFloorLimitAmount())
                fRetVal = VS_TRUE;
            break;

        case FPS_CUSTOM:
            fRetVal = fCustomFPSQualifier(pobTran);
            break;
        default:
            fRetVal = VS_FALSE;
            break;
        } /* end switch */
    } /* end if */

#endif

    if (fRetVal == VS_TRUE)
        vdSetAVS(NO_AVS);

    return (fRetVal);
} /* end fFPSQualified */

/*********************************************************************************************
* @func VS_BOOL | fFPSNoAuthRequired |
*
*       Determines if FPS transaction requires authorization.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
* @flag VS_BOOL    |  VS_TRUE       |
* @flag VS_BOOL    |  VS_FALSE      |
* @end
**********************************************************************************************/

VS_BOOL fFPSNoAuthRequired(TRANSACTION_OBJECT* pobTran) {
    VS_BOOL fRetVal = VS_FALSE;
    long int lnTransAmount;

    lnTransAmount = pobTran->srBKey.lnTotalOfTransactionAmount;

    /* if Floor Limit Check enabled, check if auth required */
    if (fGetCheckFloorLimit(pobTran)) {
        /* no authorization required if FPS Type is a Floor Limit OR
           (FPS type is FPS and issuer is VISA and
           trans amount is less than/equal to floor limit) */
        if ((inGetFPSType() == FPS_FLOOR) || ((inGetFPSType() == FPS_VISA_EXP) && (lnTransAmount <= lnGetFloorLimitAmount())))
            fRetVal = VS_TRUE;
    }
    return (fRetVal);
}

/*********************************************************************************************
* @func void | vdMakeAndSetApprCode |
*       For txns that are under the floor limit fill the
*       appr code with "FLXXXX" where XXXX are the last 4 digits of the Invoice Number.
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
* @end
**********************************************************************************************/

void vdMakeAndSetApprCode(TRANSACTION_OBJECT* pobTran) {
    char szDummyApprCode[AUTH_SIZE + 1];
    char szInvoiceNum[INV_NUM_SIZE + 1];
    char szCode[2 + 1];

    /** /pdebug(("--vdMakeAndSetApprCode--"));*/

    memset(szInvoiceNum, '\0', sizeof(szInvoiceNum));
    memset(szDummyApprCode, '\0', sizeof(szDummyApprCode));
    strcpy(szCode, "FL");
    sprintf(szDummyApprCode, szCode);
    long2str(szInvoiceNum, pobTran->srBKey.lnInvNum);
    pad(szInvoiceNum, szInvoiceNum, '0', AUTH_SIZE, RIGHT);
    vdStrNoCpy(szDummyApprCode + strlen(szDummyApprCode), szInvoiceNum + 2, 5);

    strcpy(pobTran->srBRec.szAuthCode, szDummyApprCode);
}


/*********************************************************************************************
* @func VS_BOOL | inFPSRespMessage |
*
*       If FPS transaction does not require authorization, creates response message.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
* @flag VS_BOOL    |  VS_TRUE       |
* @flag VS_BOOL    |  VS_FALSE      |
* @end
**********************************************************************************************/
#ifndef  REMOVE_CORE_FPS_RESP_MESSAGE

int inFPSRespMessage(TRANSACTION_OBJECT* pobTran) {
    char szTempAuthCode[AUTH_SIZE + 1];

    /* if the Fast Payment set up does not require an authorization,
        set the first two characters of the approval code to "FL" */
    if (fFPSNoAuthRequired(pobTran)) {
        if (pobTran->srBRec.fManual == VS_TRUE)
            vdMakeAndSetApprCode(pobTran);
        else {
            strcpy(szTempAuthCode, "SVC");
            strcat(szTempAuthCode, pobTran->szServiceCode);
            strcpy(pobTran->srBRec.szAuthCode, szTempAuthCode);
        }

        vdSGRespMsg(pobTran->srBRec.szAuthCode);
    }

    return(VS_SUCCESS);
}
#endif /* #ifndef  REMOVE_CORE_FPS_RESP_MESSAGE */


int inRunFunction(TRANSACTION_OBJECT* pobTran,int inFieldID) {
    int inRetVal = VS_ERR;
    PFI_TO pinFunction;

    if ((pinFunction = inGetFunctionPointer(inFieldID)) != NULL_PFI)
        inRetVal = pinFunction(pobTran);

    return (inRetVal);
}

int inValidateISDN_TEST_TRANSACTION(void) {
#ifdef ISDN_MODULE
    /*
        *      Currently Loaded Host ISDN?
        */
    if (!fISDN()) {
        vdSGErrorMessage(INV_HOST_MSG);
        return(VS_ERR);
    }

    /*
     *      ISDN Test Transaction Allowed?
     */
    if (!fGetICTTestTranON()) {
        vdSGErrorMessage(TRANS_NOT_ALLWD_ERR_MSG);
        return(VS_ERR);
    }
#endif

    return (VS_SUCCESS);
}

typedef int (*PFI_SHORT) (short );
/*********************************************************************************************
* @func int | inColdInitPinpad |
*
* This routine is called via the COLD_INIT_OPERATION at power-up time. It initializes
* the PinPad based on the PinPadType setting in the TCT.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc Returns the success/failure status of the operation.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inColdInitPinpad(TRANSACTION_OBJECT* pobTran) {
    int inRetVal = VS_SUCCESS;

#ifdef PINPAD_DEFINED

    char szMessage[MESSAGE_SIZE + 1];
    PFI_SHORT inPinPadSetup = (PFI) NULL;/* vsk -- added custom initialisation of Pinpad */

    vdGetMessageFromThisFile(PINPAD_MESSAGE_FILE, PINPAD_CHECK_MSG, szMessage);
    vdDisplayStatusString(szMessage);

    /* Setup appropriate function pointers in global PinPad object */
    if ((inPinPadSetup = inGetFunctionPointer(SETUP_PINPAD)) != NULL_PFI)
        inPinPadSetup(inGetPINPadType());/* vsk -- added custom initialisation of Pinpad */
    else
        inSetupPinPad(inGetPINPadType());

    if (!gfPPadPresent) {
		LOG_PRINTFF((0x08L, "gfPPadPresent = [FALSE]"));
        return VS_SUCCESS;
	} else {
		LOG_PRINTFF((0x08L, "gfPPadPresent = [TRUE]"));
	}

    /*
     * Use PinPad object function pointers to:
     * - Initialize the Pinpad
     * - Set up the PinPad idle prompt
     */
    inRetVal = inInitializePinPad();

#endif

    return inRetVal;
}

/*********************************************************************************************
* @func int | inCheckBannedCardType |
*
*       Checks TRT for banned card type.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
* @flag int    |  VS_SUCCESS    |
* @flag int    |  VS_ERR        |
* @end
**********************************************************************************************/

int inCheckBannedCardType(TRANSACTION_OBJECT* pobTran) {
    unsigned short    uiTRTCardType;

    switch (pobTran->srBRec.inTranCardType) {
    case CREDIT_CARD:
        uiTRTCardType = TRT_CREDIT_CARD;
        break;
    case DEBIT_CARD:
        uiTRTCardType = TRT_DEBIT_CARD;
        break;
    case EBT_CARD:
        uiTRTCardType = TRT_EBT_CARD;
        break;
    case PURCHASE_CARD:
        uiTRTCardType = TRT_PURCHASE_CARD;
        break;
    case FLEET_CARD:
        uiTRTCardType = TRT_FLEET_CARD;
        break;
    case ADMIN_CARD:
        uiTRTCardType = TRT_ADMIN_CARD;
        break;
    case NON_CARD:
        uiTRTCardType = TRT_NON_CARD;
        break;
    default:
        break;
    }
    if (pobTran->inChipStatus == EMV_CARD)
        uiTRTCardType = uiTRTCardType | TRT_EMV_CARD;
    //if ( uiTRTCardType & pobTran->srTRTRec.uiBannedCardTypes )
    if (uiTRTCardType & shGetBannedCardTypes(pobTran)) {
        vdDisplayMessageFromFile(NOT_SUPPORTED_MSG21, ERROR_MSG);
        return(VS_ERR);
    }
    return(VS_SUCCESS);
}

int inColdInitRadioModem(TRANSACTION_OBJECT* pobTran) {
#ifdef MOBITEX_DEFINED
    int inRetVal = 0;

    pdebug(("ColdInitRadio"));

    inRetVal = inGetRadioCommHost();

    pdebug(("Radio result %d", inRetVal));
    if (inRetVal != VS_ERR && srGDS.fWirelessModem) {
        if (inLoadDefaultHost(inRetVal) != VS_SUCCESS)
            return (VS_ERR);

        vdSetHostHandle(inRetVal);


        if (obCommunication.inLinkType != MOBITEX_COMM) {
            if (obCommunication.inLinkType != NO_COMM) {
                if (obCommunication.inDeinitialize)
                    obCommunication.inDeinitialize(&obCommunication);
            }

            vdDisplayMessageFromFile(NO_WIRELESS_HOST_MSG21, WARNING_MSG);
            return(VS_SUCCESS);
        }

        vdInitializeMobitexComm(&obCommunication);
        pdebug(("Call Init Radio"));
        if ((inInitRadioModem() != VS_SUCCESS) && (inInitRadioModem() != VS_SUCCESS)) {
            pdebug(("Deinit Mobitex"));
            //inDeInitMobitexCommunication(&obCommunication);

            // Display "NO SIGNAL" and wait for keypress
            vdDisplayMessageFromFile(NO_RADIO_SIGNAL_MSG, ERROR_MSG);
            srGDS.fWirelessActive = VS_FALSE;
            return(VS_SUCCESS);
        }

        srGDS.fWirelessActive = VS_TRUE;
    } /* end if Wireless host in MCT */

#endif  // MOBITEX_DEFINED

    return(VS_SUCCESS);
} /* end func inColdInitRadioModem() */

int MDLFUNCS_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}


#undef MDLFUNCS_C
